#ifndef CONFIGMANAGER_HPP_INCLUDED
#define CONFIGMANAGER_HPP_INCLUDED

#include <QtCore/QString>
#include <QtCore/QVector>
#include <QtCore/QObject>
#include <QtCore/QTextStream>
#include <QtXml/QXmlDefaultHandler>
#include <QtXml/QXmlInputSource>
#include <QtXml/QXmlSimpleReader>
#include "model/Shortcut.hpp"

#define CONFIG_FILE "configuration.xml"

enum RepeatMode {
    REPEAT_NONE=0,
    REPEAT_ONE=1,
    REPEAT_ALL=2
};

/** This class is used to manages the configurtion file that is in INI */
class ConfigManager : public QObject, public QXmlDefaultHandler {
    Q_OBJECT
    private:
        QFile cfgFile;
        QTextStream out;
        QString currentName;
        /// \brief Elapsed time in second after the play count will be incremented
        unsigned int countAfterTime;
        bool reduceVolumeInsteadOfMuting,resumeAtStartup;
        unsigned int lastPositionPlayed, volume, repeatMode, shuffleMode;
        //collection scan filter
        unsigned int minTime, maxTime;//min/max audio time in seconds
        unsigned short minBitrate, maxBitrate;
        unsigned short minChannels, maxChannels;
        bool onlyWithTags;
        QString formats;     //authorized audio formats separated by comas
        //opened playlist

        QVector<QString> collection; //collection folders
        /// \brief Shortcut list
        QVector<Shortcut*> shortcuts;
        //playback settings
        bool fadeOnStop, fadeOnSkip, fadeOnNext, fadeForAlbum;
        unsigned int fadeInTime, fadeOutTime;
        bool useReplayGainIfAvailable, replayGainApplyCompression;//replayGainApplyCompression: to avoid cuts
        float replayGainPreAmp;
        //QString replayGainMode; //radio (egalized volume for all tracks), album (best volume for all tracks)
        //QString outputDevice;
        unsigned int bufferTime;
        bool monoPlayback;
        //collection
        bool displayMissing,removeMissing, updateCollectionAtStartup, monitorOnChangeOnCollection;//displayMissing: display missing file in the library
        QString preferredCover;
        //playlist
        //bool playlistRemoveMissing;
        /// \brief Proxy settings: blank for system settings, internet:// for a direct connection to internet, http|socks://url:port:username:password
        QString proxy;
        //convert settings for MP3, FLAC, vorbis, ...
        //find settings: collection and music services selection
        //song information
        float songInfoFontSize;
        unsigned int songInfoNetworkTimeout;
        //list of selected websites
        //notifications
        //mode:none,tray,OSD
        unsigned int notificationDuration; //0 for disabled or -1?
        bool notificationOnVolumeChange, notificationOnRepeatChange, notificationHasAlbumCover,notificationHasCustomText;
        QString notificationCustomBrief, notificationCustomBody;
        //misc
        bool firstRun, defaultPlayer;
        //unsigned minimalTime; //minimum audio time in second for an audio file: if less than this time, the track will not be added to the collection
        QString mask;//renaming mask for track,album, ...
    public:
        ConfigManager();
        ~ConfigManager();
        /** @brief Load the configuration file defined with CONFIG_FILE
         * @return false if an error occurs while loading
         */
        bool load();
        /** @brief Save the configuration file
         */
        void save();
        /** @brief Add a folder to the collection
         * @param path Folder path
         */
        void addFolder(QString path);
        /** @brief Reset the configuration except for the collection folders
         */
        void setDefaultConfiguration();
        //getters
        bool hasFadeOnStop();
        bool hasFadeOnSkip();
        bool hasFadeOnNext();
        bool hasFadeForAlbum();
        unsigned int getFadeInTime();
        unsigned int getFadeOutTime();
        bool hasReplayGainEnabled();
        bool hasReplayGainCompression();
        float getReplayGainPreAmp();
        unsigned int getBufferTime();
        bool isMonoPlayback();
        bool hasUpdateOnCollectionAtStartup();
        bool hasMonitorOnChangeCollection();
        bool hasMissingDisplayed();
        QString getPrefferedCovers();
        QVector<QString> * getCollection();
        QString getProxySettings();
        QVector<Shortcut*> *getShortcuts();
        float getSongInfoFontSize();
        unsigned int getSongInfoNetworkTimeout();
        unsigned int getNotifyDuration();
        bool hasNotificationOnVolumeChange();
        bool hasNotificationOnRepeatChange();
        bool hasNotificationHasAlbumCover();
        bool hasNotificationHasCustomText();
        QString getNotificationCustomBrief();
        QString getNotificationCustomBody();
        unsigned int getMinimumTime();
        unsigned int getMaximumTime();
        QString getAuthorizedFormats();

        bool hasTags();
        unsigned int getCountAfterTime();
        void setCountAfterTime(unsigned int t=0);
        bool isVolumeReducedIsteadOfMuting();
        bool isResumingAtStartup();
        unsigned int getLastPositionPlayed();
        unsigned int getVolume();
        unsigned int getRepeatMode();
        unsigned int getShuffleMode();
        unsigned int getMinTime();
        unsigned int getMaxTime();
        unsigned short getMinBitrate();
        unsigned short getMaxBitrate();
        unsigned short getMinChannels();
        unsigned short getMaxChannels();
        void setVolumeReducedInsteadOfMuting(bool v=false);
        void setLastPositionPlayed(unsigned int v=0);
        void setVolume(unsigned int v=0);
        void setRepeatMode(unsigned int v=0);
        void setShuffleMode(unsigned int v=0);
        void setMinTime(unsigned int v=0);
        void setMaxTime(unsigned int v=0);
        void setMinBitrate(unsigned short v=0);
        void setMaxBitrate(unsigned short v=0);
        void setMinChannels(unsigned short v=0);
        void setMaxChannels(unsigned short v=0);

        //setters
        void setFadeOnStop(bool v = true);
        void setFadeOnSkip(bool v = false);
        void setFadeOnNext(bool v = true);
        void setFadeForAlbum(bool v = true);
        void setFadeInTime(unsigned int v = 2000);
        void setFadeOutTime(unsigned int v = 2000);
        void setReplayGainIfAvailable(bool v = false);
        void setReplayGainCompression(bool v = false);
        void setReplayGainPreAmp(float v = 0);
        void setBufferTime(unsigned int v = 4000);
        void setMonoPlayback(bool v = false);
        void setDisplayMissing(bool v = false);
        void setRemoveMissing(bool v = false);
        void setUpdateCollectionAtStartup(bool v = false);
        void setMonitorOnChangeOnCollection(bool v = false);
        void setPrefferedCover(QString v = "front,cover");
        void setProxySettings(QString v = "");
        void setSongInfoFontSize(float v = 8.5);
        void setSongInfoNetworkTimeout(unsigned int v = 2500);
        void setNotificationDuration(unsigned int v = 3000);
        void setNotificationOnVolumeChange(bool v = false);
        void setNotificationRepeatChange(bool v = false);
        void setNotificationHasAlbumCover(bool v = false);
        void setNotificationHasCustomText(bool v = false);
        void setNotificationHasCustomBrief(QString v = "");
        void setNotificationHasCustomBody(QString v = "");

        //XML SAX callbacks
        virtual bool startElement(const QString &namespaceURI,  const QString &localName, const QString &qName, const QXmlAttributes &attribs);
        virtual bool endElement  (const QString &namespaceURI, const QString &localName, const QString &qName);
        virtual bool characters  (const QString &str );
        virtual bool fatalError  (const QXmlParseException &e);
    signals:
        /** @brief Perform a scan on the collection to add new tracks and to check for changes on files
         */
        void updateCollection();
};

#endif // CONFIGMANAGER_HPP_INCLUDED
